package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import com.itheima.utils.DateUtils;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/report")
public class ReportController {

    @Reference
    private MemberService memberService;

    @Reference
    private SetmealService setmealService;

    @Reference
    private ReportService reportService;

    @RequestMapping("/getMemberReport")
    public Result getMemberReport() {
        Map<String, Object> map = new HashMap<>();
        List<String> months = new ArrayList<>();
        //获取当前时间的时间对象
        Calendar calendar = Calendar.getInstance();
        //12个月前的今天
        calendar.add(Calendar.MONTH, -12);
        //遍历每一个月
        for (int i = 1; i <= 12; i++) {
            calendar.add(Calendar.MONTH, 1);
            Date time = calendar.getTime();
            months.add(new SimpleDateFormat("yyyy.MM").format(time));
        }
        map.put("months", months);
        //根据日期获取会员个数
        List<Integer> memberCount = memberService.findMemberCountByDate(months);
        map.put("memberCount", memberCount);
        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
    }

    //套餐预约比饼图
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        Map<String, Object> map = new HashMap<>();
        try {
            //获取套餐种类数量等信息
            List<Map<String, Object>> setmealCount = setmealService.findSetmealCount();
            if (setmealCount != null && setmealCount.size() > 0) {
                map.put("setmealCount", setmealCount);
                List<String> setmealNames = new ArrayList<>();
                for (Map<String, Object> setmealMap : setmealCount) {
                    //获取套餐名称
                    String name = (String) setmealMap.get("name");
                    setmealNames.add(name);
                }
                map.put("setmealNames", setmealNames);
                return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
            } else {
                return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    //查询运营数据
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() {
        try {
            Map<String, Object> map = reportService.getBusinessReportData();
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    //导出PDF报表
    @RequestMapping("/exportBusinessReport4PDF")
    public Result exportBusinessReport4PDF(HttpServletRequest request, HttpServletResponse response) {
        try {
            //获取报表数据
            Map<String, Object> map = reportService.getBusinessReportData();

            if (map != null){
                List<Map<String,Object>> hotSetmeal = (List<Map<String, Object>>) map.get("hotSetmeal");

                //动态获取模板文件的绝对路劲（File.separator为生成不同的分割符）
                String jrxmlPath = request.getSession().getServletContext().getRealPath("template" + File.separator + "health_business3.jrxml");
                String jasperPath=request.getSession().getServletContext().getRealPath("template" + File.separator + "health_business3.jasper");

                //编译模板
                JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);

                ////填充数据---使用JavaBean数据源方式填充
                JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath,
                        map,
                        new JRBeanCollectionDataSource(hotSetmeal)
                );

                //将文件以指定的格式进行下载
                ServletOutputStream os = response.getOutputStream();
                //文件类型为PDF格式
                response.setContentType("application/pdf");
                //以附件形式进行下载
                response.setHeader("content-Disposition", "attachment;filename=report.pdf");

                //输出文件
                JasperExportManager.exportReportToPdfStream(jasperPrint,os);

                os.flush();
                os.close();
                return null;
            }else {
                return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    //导出Excel报表
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response) {
        try {
            //获取报表数据
            Map<String, Object> map = reportService.getBusinessReportData();

            if (map != null){
                //获取单个返回值数据
                String reportDate = (String) map.get("reportDate");
                Integer todayNewMember = (Integer) map.get("todayNewMember");
                Integer totalMember = (Integer) map.get("totalMember");
                Integer thisWeekNewMember = (Integer) map.get("thisWeekNewMember");
                Integer thisMonthNewMember = (Integer) map.get("thisMonthNewMember");
                Integer todayOrderNumber = (Integer) map.get("todayOrderNumber");
                Integer thisWeekOrderNumber = (Integer) map.get("thisWeekOrderNumber");
                Integer thisMonthOrderNumber = (Integer) map.get("thisMonthOrderNumber");
                Integer todayVisitsNumber = (Integer) map.get("todayVisitsNumber");
                Integer thisWeekVisitsNumber = (Integer) map.get("thisWeekVisitsNumber");
                Integer thisMonthVisitsNumber = (Integer) map.get("thisMonthVisitsNumber");
                List<Map<String,Object>> hotSetmeal = (List<Map<String, Object>>) map.get("hotSetmeal");

                //动态获取模板文件的绝对路劲（File.separator为生成不同的分割符）
                String realPath = request.getSession().getServletContext().getRealPath("template" + File.separator + "report_template.xlsx");
                //根据模板文件创建Excel对象
                XSSFWorkbook sheets = new XSSFWorkbook(new FileInputStream(new File(realPath)));
                //获取表格单元
                XSSFSheet sheet = sheets.getSheetAt(0);
                //获取所在行
                XSSFRow row = sheet.getRow(2);
                //获取所在列
                XSSFCell cell = row.getCell(5);
                //日期赋值
                cell.setCellValue(reportDate);

                row=sheet.getRow(4);
                cell=row.getCell(5);
                cell.setCellValue(todayNewMember);//今日新增会员

                cell=row.getCell(7);
                cell.setCellValue(totalMember);//总会员数

                row=sheet.getRow(5);
                cell=row.getCell(5);
                cell.setCellValue(thisWeekNewMember);//本周新增会员数

                cell=row.getCell(7);
                cell.setCellValue(thisMonthNewMember);//本月新增会员数

                row = sheet.getRow(7);
                cell=row.getCell(5);
                cell.setCellValue(todayOrderNumber);//今日预约人数

                cell=row.getCell(7);
                cell.setCellValue(todayVisitsNumber);//今日到诊人数

                row=sheet.getRow(8);
                cell=row.getCell(5);
                cell.setCellValue(thisWeekOrderNumber);//本周预约人数

                cell=row.getCell(7);
                cell.setCellValue(thisWeekVisitsNumber);//本周到诊人数

                row=sheet.getRow(9);
                cell= row.getCell(5);
                cell.setCellValue(thisMonthOrderNumber);//本月预约人数

                cell=row.getCell(7);
                cell.setCellValue(thisMonthVisitsNumber);//本月到诊人数

                //热门套餐
                int hotNumber = 12;
                for (Map<String, Object> hotMap : hotSetmeal) {
                    String name = (String) hotMap.get("name");
                    Long setmeal_count = (Long) hotMap.get("setmeal_count");
                    BigDecimal proportion = (BigDecimal) hotMap.get("proportion");
                    row=sheet.getRow(hotNumber);
                    row.getCell(4).setCellValue(name);
                    row.getCell(5).setCellValue(setmeal_count);
                    row.getCell(6).setCellValue(proportion.doubleValue());
                    hotNumber++;
                }

                //将文件以指定的格式进行下载
                ServletOutputStream os = response.getOutputStream();
                //文件类型为excel格式
                response.setContentType("application/vnd.ms-excel");
                //以附件形式进行下载
                response.setHeader("content-Disposition", "attachment;filename=report.xlsx");

                sheets.write(os);
                os.flush();
                os.close();
                sheets.close();
                return null;
            }else {
                return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    public static void main(String[] args) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -12);
        for (int i = 1; i <= 12; i++) {
            calendar.add(Calendar.MONTH, 1);
            Date time = calendar.getTime();
            //  System.out.println(DateUtils.parseDate2String(time));
            System.out.println(new SimpleDateFormat("yyyy.MM").format(time));
        }
    }
}
